﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using UnityEditor;
using UnityEngine;
using UnityEngine.UI;


namespace RStudio.UIFramwork.Editor
{
    public class TemplateUtil
    {
        /// <summary>
        /// 验证|组件有效性
        /// </summary>
        public static bool Valied<T>(GameObject target) where T : UnityEngine.Component
        {
            if (!target)
            {
                EditorUtility.DisplayDialog("错误", "请选择被程序化对象", "了解");
                return false;
            }

            if (!target.TryGetComponent(out T _))
            {
                EditorUtility.DisplayDialog("错误", $"被程序化对象要求为 {typeof(T).Name} 对象，请检查！", "了解");
                return false;
            }

            return true;
        }

        /// <summary>
        /// 验证|节点有效性
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        public static bool ValidNode(Transform node)
        {
            if (string.IsNullOrEmpty(node.transform.name))
            {
                EditorUtility.DisplayDialog("错误", $"检测到空名称对象（父对象：{node.parent?.name}），已跳过", "了解");
                return false;
            }

            bool isIgnored = node.name.Contains("~");
            if (isIgnored)
            {
                Debug.LogWarning($"已忽略对象及其子对象：{node.name}（名称含~）");
                return false;
            }

            return true;
        }



        /// <summary>
        /// 创建|预制体
        /// </summary>
        /// <param name="target">目标对象</param>
        /// <param name="outputPath">预制体输出路径（相对于Assets）</param>
        public static void DoCreatePrefab(GameObject target, string outputPath)
        {
            if (!target) return;

            // 检查是否为已关联的预制体（若已关联则不重复创建）
            PrefabInstanceStatus prefabStatus = PrefabUtility.GetPrefabInstanceStatus(target);
            if (prefabStatus == PrefabInstanceStatus.Connected)
            {
                EditorUtility.DisplayDialog("提示", $"\"{target.name}\" 已关联预制体，无需重复创建", "了解");
                return;
            }

            // 构建完整路径并创建文件夹
            string fullOutputPath = $"{Application.dataPath}/{outputPath}";
            RStudio.UIFramwork.Editor.UnitFileUtil.CreateFolder(fullOutputPath);

            // 保存预制体
            string prefabSavePath = $"{fullOutputPath}/{target.name}.prefab";
            PrefabUtility.SaveAsPrefabAsset(target, prefabSavePath);
            AssetDatabase.Refresh();
        }

        /// <summary>
        /// 组件|名称规范
        /// </summary>
        /// <param name="component"></param>
        /// <param name="componentName"></param>
        public static void StandaradNameComponent(Component component, out string componentName)
        {
            string nodeName = component.transform.name.Replace(" ", "_");

            nodeName = Regex.Replace(nodeName, "[^a-zA-Z0-9_]|^[\\d]", "");

            // 按组件类型定义统一前缀（便于识别）
            componentName = component switch
            {
                Button => $"BTN_{nodeName}",
                CanvasRenderer => $"CRender_{nodeName}",

                Image => $"IMG_{nodeName}",

                RectTransform => $"RT_{nodeName}",
                RawImage => $"RIMG_{nodeName}",

                Slider => $"SLI_{nodeName}",
                ScrollRect => $"SR_{nodeName}",

                Toggle => $"TGL_{nodeName}",
                Text => $"TXT_{nodeName}",
                //TextMeshProUGUI => $"TMP_{nodeName}",

                UIMask => $"MASK_{nodeName}",
                _ => $"{component.GetType().Name}_{nodeName}",
            };
        }

        /// <summary>
        /// 节点|名称规范
        /// </summary>
        /// <param name="node"></param>
        /// <param name="nodeName"></param>
        /// <returns></returns>
        public static bool StandaradNameNode(Transform node, out string nodeName)
        {
            // 01. 去除首末空格
            nodeName = node.name.Trim();

            // 02. 替换中间空格字符|避免路径错误
            if (nodeName.Contains(" "))
            {
                nodeName = nodeName.Replace(" ", "_");
                node.name = nodeName;
                EditorUtility.DisplayDialog("提示", $"对象名称\"{node.name}\"包含空格，已自动替换为\"{nodeName}\"", "了解");
            }

            return true;
        }



        /// <summary>
        /// 收集目标节点及其子节点组件信息
        /// </summary>
        public static void DoCollectComponents(Transform node, string nodePath, List<ComponentDetail> details, bool containChild = true)
        {
            // 2. 遍历节点组件
            Component[] components = node.GetComponents<Component>();
            Array.ForEach(components, component =>
            {
                // 过滤不需要的基础组件（如Transform，避免冗余）
                if (component is Transform) return;

                // 获取组件的规范名称
                bool isStandard = TemplateUtil.StandaradNameNode(node, out string nodeName);
                bool isContaind = details.Find(e => e.Component == component) != null;

                if (isStandard && !isContaind)
                {
                    TemplateUtil.StandaradNameComponent(component, out string componentName);
                    details.Add(new ComponentDetail()
                    {
                        Component = component,
                        Name = componentName,
                        NodePath = nodePath
                    });
                }
            });

            if (containChild)
            {
                DoCollectChildComponents(node, nodePath, details);
            }
        }

        /// <summary>
        /// 仅收集目标子节点组件信息
        /// </summary>
        public static void DoCollectChildComponents(Transform node, string nodePath, List<ComponentDetail> details)
        {
            // 3. 递归处理子节点
            if (node.childCount == 0) return;

            // 获取直接子节点（获取所有有效子节点）
            Transform[] childs = node.Cast<Transform>().Where(t => t.parent == node).Where(t => ValidNode(t)).ToArray();

            foreach (Transform child in childs)
            {
                // 构建子节点路径（根节点的子节点直接用名称，非根节点拼接父路径）
                string childPath = string.IsNullOrEmpty(nodePath) ? child.name : $"{nodePath}/{child.name}";
                // 迭代子节点
                DoCollectComponents(child, childPath, details);
            }
        }



        /// <summary>
        /// 收集目标节点及其子节点组件信息
        /// </summary>
        /// <param name="rootNode">根节点</param>
        /// <returns>组件-命名映射表</returns>
        public static void DoCollectComponentsExp(Transform node, string nodePath, List<ComponentDetail> details, bool containChild = true)
        {
            containChild = !GetComponents(node, out Component[] components);

            Array.ForEach(components, component =>
            {
                // 获取组件的规范名称
                bool isStandard = TemplateUtil.StandaradNameNode(node, out string nodeName);
                bool isContaind = details.Find(e => e.Component == component) != null;

                if (isStandard && !isContaind)
                {
                    TemplateUtil.StandaradNameComponent(component, out string componentName);
                    details.Add(new ComponentDetail()
                    {
                        Component = component,
                        Name = componentName,
                        NodePath = nodePath
                    });
                }
            });

            if (containChild && !node.gameObject.name.StartsWith("!"))
            {
                DoCollectChildComponentsExp(node, nodePath, details);
            }
        }

        public static void DoCollectChildComponentsExp(Transform node, string nodePath, List<ComponentDetail> details)
        {
            // 3. 递归处理子节点
            if (node.childCount == 0) return;

            // 获取直接子节点（获取所有有效子节点）
            Transform[] childs = node.Cast<Transform>().Where(t => t.parent == node).Where(t => ValidNode(t)).ToArray();

            foreach (Transform child in childs)
            {
                // 构建子节点路径（根节点的子节点直接用名称，非根节点拼接父路径）
                string childPath = string.IsNullOrEmpty(nodePath) ? child.name : $"{nodePath}/{child.name}";
                // 迭代子节点
                DoCollectComponentsExp(child, childPath, details);
            }
        }

        /// <summary>
        /// 组件|白名单
        /// </summary>
        /// <param name="node"></param>
        /// <remarks>
        /// 这些组件将不再需要索引子对象
        /// </remarks>
        public static bool GetComponents(Transform node, out Component[] components)
        {
            components = node.GetComponents<Component>();
            var match = components.Where(component =>
                component is Button ||
                component is Toggle ||
                component is Slider ||
                component is Dropdown ||
                component is ScrollRect ||
                component is UIWidget).ToArray();

            return match.Length != 0 && match != null;
        }
    }
}